/***************************************************************
Title: OLT

Info:
Uart1 - feeder
Uart2 - Optical
SPI2  - DBA Controller communication use full 32MHZ
max ethernet frame size is 100byte


****************************************************************/
#include<p24fj128ga006.h>
#include <libpic30.h>
#include "main.h"





_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & FWDTEN_OFF)
_CONFIG2(FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL)



//Initialize 
void init_timer1(void)
{
   _T1IP = 4; //set timer1 priority (4 = default)
   TMR1 = 0; //clear the timer 
   PR1 = 34; //set the period register ( 25000 *64*1 cycle(62.5ns)
   T1CON = 0x8020; //check T1CON register (1:64)
   _T1IF = 0; //clear interrupt flag
   _T1IE = 1; //enable T1 interrupt source   
}

void init_uart1(void)
{
   //TX
   U1BRG = 35;//init U1BRG reg 8
   U1MODE = 0x8008;//set the number 8,n,1
   U1STA = 0x0400;//enable uart module

   //RX
   IEC0bits.U1RXIE = 1;//Set enable rx interrupt
   _U1RXIP = 0x07;//interrupt prirority IPC2
   //urxsel<1:0> uxsta<7:6> U1STA 00, interrupt each char in
  
}
void init_uart2(void)
{
   //TX
   U2BRG = 35;//init U1BRG reg 115.2kbps
   U2MODE = 0x8008;//set the number 8,n,1
   U2STA = 0x0000;//enable uart module

   //RX
   IEC1bits.U2RXIE = 1;//Set enable rx interrupt
   _U2RXIP = 0x07;//interrupt prirority IPC2
   //urxsel<1:0> uxsta<7:6> U2STA 00, interrupt each char in
  
}

void wdt_(void)
{
    if(wdt_ctr>10000)
    {
        wdt_led = wdt_led ^ 0x01;
        wdt_ctr = 0x00;
    }
}

void buffer_clr(void)
{
   if(in_ctr > 100)
   {
     in_ctr = 0x00;
   }
}

/**************************************************************************
OLT Network management segmnent
***************************************************************************/

void GATE_Normal(unsigned char DA_pointer,unsigned char flags, unsigned char *data)
{
    int i,byte_cnt;//,j,pointer;
    //unsigned char dat_test;
    //clr buffer
    for(i=0;i<40;i++)
    {
       EthernetMPCP[i]=0;
    }
   
    //Preamble
    EthernetMPCP[0] = SPD;
    EthernetMPCP[1] = Reserved;
    EthernetMPCP[2] = Reserved;
    EthernetMPCP[3] = SLD;
    EthernetMPCP[4] = Reserved;
    EthernetMPCP[5] = Reserved;
    for(i=0;i<2;i++)
    {
       EthernetMPCP[i+6] = LLID_table[DA_pointer][i];  
    }
    EthernetMPCP[8] = 0xAA;//CRC8
    //MPCP 
    for(i=0;i<6;i++)//DA
    {           
      EthernetMPCP[9+i] =  MACAddrTable[DA_pointer][i];//DA
    }  
    for(i=0;i<6;i++)//SA
    {           
      EthernetMPCP[15+i] =  OLT_MACAddr[i];//SA
    }   
    EthernetMPCP[21] = 0x88;//type_length
    EthernetMPCP[22] = 0x08;//type_length
    EthernetMPCP[23] = 0x00;//opcode
    EthernetMPCP[24] = 0x02;//opcode
    EthernetMPCP[25] = (timer_counter32 & 0x000000FF);//timestamp
    EthernetMPCP[26] = (timer_counter32 & 0x0000FF00)>>8;//timestamp
    EthernetMPCP[27] = (timer_counter32 & 0x00FF0000)>>16;//timestamp
    EthernetMPCP[28] = (timer_counter32 & 0xFF000000)>>24;//timestamp
    //EthernetMPCP[29] = flags;//number of grand/flag
    for(i=0;i<25;i++)//copy data
    {
      EthernetMPCP[29+i] = data[i];
    }
    EthernetMPCP[70] = 'A';//number of grand/flag
    EthernetMPCP[71] = 0x0D;//number of grand/flag
    EthernetMPCP[72] = 0x0A;//number of grand/flag
    
    
    TX2EN = 1;//enable uart module
    __delay32(5000);
    for(byte_cnt=0;byte_cnt<73;byte_cnt++)//send to optical sizeof(EthernetMPCP)
    {
       U2TXREG = EthernetMPCP[byte_cnt];      
       //__delay32(30000);//delay for cater the reflection
       __delay32(20000);
    }
    TX2EN = 0;//enable uart module
    
}



void grant_gen_1st_boot(void)
{
    int i,z,j;    
    unsigned char temp[20];    
    unsigned char *temp_store;

    if(grants_reg_status == 0x00)
    {  
      capture_delay(0x01); //capture   
      for(i=0;i<onu_ctr;i++)
      {      
        if(report_list[i][0]==0x00)//no report
        {
           grants_list[i][0] = 0x01; // data set
           grants_list[i][1] = 0x01; // no of gtants/flag
    
           // start time   
           if(i == 0)        
              x = timer_counter32 + processing_delay;
           else
           { 
             x = changeByte2Long(grants_list[i-1][2],grants_list[i-1][3],grants_list[i-1][4],grants_list[i-1][5]);          
           }
           __delay32(10000);
           grant_alc =  x + 1500;   //1 tick = 40us       
           temp_store = changeLong2Byte(grant_alc); 
           grants_list[i][2] = temp_store[0];
           grants_list[i][3] = temp_store[1];
           grants_list[i][4] = temp_store[2];
           grants_list[i][5] = temp_store[3]; 

           //length
           grants_list[i][6] = 0x05; // 1500   little indiant need to check************ changing for testing = 
           grants_list[i][7] = 0xB0;                     
                   
        }
        //else        
      }
    }
    //send grant
    for(z=0;z<onu_ctr;z++)//No of onu
    {       
       for(j=0;j<25;j++)//copy grant to mpcp
       {
            temp[j] = grants_list[z][j+1];
            grants_list[z][j] = 0x00; //clr buffer after transfer
       }                        
       GATE_Normal(z,0x00,temp);//send gate for alive  
   
      
       ///TX2EN = 0;//enable uart module  
           
    }
    grants_reg_status=0x03;  
    capture_delay(0x02);//capture and send  
}



int main(void)
{
    init_timer1();
    init_uart1();
    init_uart2();

    U1TXREG = 'A';      
    __delay32(1500); 

    grants_reg_status = 0x00;
    grant_gen_1st_boot();

    while(1)
    {
       process_URX1();
       process_URX2();
	   buffer_clr();
       //grants_reg_status = 0x00;
       /*****add user define function below this line******/
       dba(); 
	   	
    }
}






/***********************************************************
Interrupt handler
************************************************************/
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt()
//void __attribute__((interrupt, auto_psv)) _T1Interrupt()
{
   timer_counter32++;
   if(timer_counter32 == 0xFFFFFFFF)
       timer_counter32 = 0x00;
   wdt_ctr++;  

   _T1IF = 0;
}

void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt()
{
   unsigned char datax;

   datax = U1RXREG;
   if((datax == 0x02)&&(in_ctr1 == 0x00))  //SOF detect
   {
           in1_buffer[in_ctr1++] = datax;          
   }
   else if(in_ctr1 != 0x00)//normal data
   {
            in1_buffer[in_ctr1++] = datax;
   }

   if((in_ctr1 != 0x00)&&(in1_buffer[in1_buffer[4]+5] == 0x03))//EOF detech
   {
            //U1TXREG = 0x01;
            in1_buffer[in1_buffer[4]+5] = 0x00;
            URX1_Ready = 0x01;
            in_ctr1 = 0x00;
   }

   IFS0bits.U1RXIF = 0;

}

void __attribute__((interrupt, no_auto_psv)) _U2RXInterrupt()
{
   unsigned char data;
   
   data = U2RXREG; 
   //U1TXREG = 0x85;//debug
   if((data == 0x02)&&(in_ctr == 0x00))
   {
      in2_buffer[in_ctr++]=data;       
   }
   else if((data == 0x55)&&(in_ctr == 0x01))
   {
      in2_buffer[in_ctr++]=data;           
   }
   else if((data == 0x55)&&(in_ctr == 0x02))
   {
      in2_buffer[in_ctr++]=data;      
   }
   else if((data == 0xD5)&&(in_ctr == 0x03))
   {
      in2_buffer[in_ctr++]=data;      
   }
   else if((data == 0x55)&&(in_ctr == 0x04))
   {
      in2_buffer[in_ctr++]=data;     
   }
   else if((data == 0x55)&&(in_ctr == 0x05))
   {
      in2_buffer[in_ctr++]=data;
             
   }
   else if(in_ctr>5)
   {
     in2_buffer[in_ctr++]=data;
     if(in_ctr == 23)
     {
         length_type = (((in2_buffer[21] | length_type)<< 8)| in2_buffer[22]);
     }
     else if(in_ctr > 70)
     {
         if(length_type <= 0x05DE)//data
         {
              if(in_ctr == length_type)
              {
                 URX2_Ready = 0x02;
                 in_ctr = 0x00; 
              } 
         }
         else//ether type
         {
              if(in_ctr == 73)//MPCP
              {
                 
                 URX2_Ready = 0x01;
                 in_ctr = 0x00; 
              } 
         }
     } 
   }
 
   IFS1bits.U2RXIF = 0;   


}


